"""
初次使用 urllib 实现数据爬取：
1、urllib.request.urlopen(url,data=None)：发送get请求，返回的是 response 对象 HTTPResponse。
data不为空时，表示 POST 请求，反之为 GET 请求。
HTTPResponse 对象有多个方法：
read(n)：读取响应数据，n 表示读取 n 个字节数
readline()：读取当前行的数据
readlines()：读取所有行的数据
headers：响应头信息
code：响应码，一般为 200 表示请求成功

2、urllib.parse.quote(wd)：将中文进行编码
quote 只是单纯地将中文进行编码，编译为十六进制

3、urllib.request.urlretrieve(url=,filename=,data=None)：下载远程数据到本地，包括网页、图片、视频。
data 不为空时，表示 POST 请求，反之为 GET 请求。
4、urllib.request.Request(url=,data=,headers=)：设置/封装请求头
Request(url,headers={})
5、with...as：上下管理器的使用，文件对象进行上下文时触发__enter__(self)方法，退出时触发__eixt__(self)方法
"""
from urllib.request import urlopen, urlretrieve, Request
from urllib.parse import quote


# import ssl

# 解决 SSL
# 导入 ssl 包
# 请求前设置 https 上下文
# ssl._create_default_https_context = ssl._create_unverified_context


# 封装一个函数，用于爬取网页内容
def search_baidu(wd='爬虫'):
	# url的组成：协议+主机+端口+请求资源路径+请求参数+锚点
	# http://www.baidu.com:80/s?wd=爬虫/#1
	# url：网络资源接口，或统一资源定位符
	url = 'https://www.baidu.com/s?wd=%s'
	# quote 对输入的中文进行编码
	# % 的是作用是格式化操作
	# ‘word: %s’ % good，good 替换 %s
	# Request 用于封装请求头内容
	# 生成请求对象，封装请求的 url 和 headers
	# 这里的变量 request 相当于 url，它只是封装了 headers
	# 格式：Request(url,data=None,headers=)
	request = Request(url % quote(wd), headers={
		# 设置Cookie后，爬取程序可以记住用户登录状态，如果是在用户登录状态下获取的Cookie的话。
		# 当直接使用浏览器搜索“爬虫”和使用爬虫程序搜索，两个结果相同
		# 而当不设置Cookie，爬虫抓取到的结果与直接搜索的结果有差异，如没有用户登录状态信息
		'Cookie': 'BIDUPSID=1B3AE86D1BD840AF1BC36FECE91C076B; PSTM=1610086369; BAIDUID=1B3AE86D1BD840AFD51F2C61C653BC4C:\
		FG=1; BD_UPN=12314353; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; __yjs_duid=1_164c67506903ec5c2882a145bbe2b9ed1610\
		087866484; BDUSS=dDNDViNWg5ZFZRM2FkMC1ud3gzQVNHWXBFTGNaU3BZOE13aEUyZmYyUEo3UjlnSVFBQUFBJCQAAAAAAAAAAAEAAAAenUXox\
		7OzqsDr6eTX7cKlwLwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMlg-F~JYPhfRm; BDUSS_BFESS=d\
		DNDViNWg5ZFZRM2FkMC1ud3gzQVNHWXBFTGNaU3BZOE13aEUyZmYyUEo3UjlnSVFBQUFBJCQAAAAAAAAAAAEAAAAenUXox7OzqsDr6eTX7cKlwLw\
		AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMlg-F~JYPhfRm; BD_CK_SAM=1; PSINO=3; delPer=1;\
		 H_PS_PSSID=33423_33442_31660_33284_33287_33413_26350_33264_33394_33385_33370; COOKIE_SESSION=1527_0_6_0_8_10_1_\
		 0_4_6_1_3_105556_0_0_0_1610490740_0_1610494268%7C9%230_0_1610494268%7C1; sug=3; sugstore=0; ORIGIN=2; bdime=0',

		# 反爬虫策略，设置 UA，模拟浏览器访问 web 服务器
		'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.\
		141 Safari/537.36'
	})

	# urlopen 表示向 web 服务器发送请求
	# 如果请求成功，服务器会返回响应数据
	# 返回的数据类型为 response 响应对象 HTTPResponse
	response = urlopen(request)  # <class 'http.client.HTTPResponse'>
	print(type(response))

	assert response.code == 200  # 响应码
	print('请求发送成功！')
	# print(response.headers) # 获取响应头
	# print(response.status) # 响应码 200
	# response.geturl # 请求的url
	# response.getheaders()  # 获取响应头
	# 响应头的中所有信息均可通过 响应对象调用获取

	# 读取从服务器返回的响应数据
	# read(n): 可以添加参数，表示读取 n 个字节
	# read()读取的数据为二进制，需要转码操作
	# 字节->字符  解码decode
	# 字符->字节 编码encode
	# 文件流：read()只能读取一次，读取完后，相当于光标到了文件末尾，read()读取光标后面的内容
	bytes_ = response.read()
	print(type(bytes_))  # <class 'bytes'>

	# 将读取到的响应数据写入一个文件中，如写入 html 文件
	# with...as: 上下文管理器，打开一个对象会自动关闭，不用手动关闭
	# 当对象进入上下文时，调用对象的__enter__(self)方法
	# 当对象退出上下文时，调用对象的__exit__(self, except_type, except_value, except_tb)方法
	# file 变量接收的是 open() 函数返回的 文件对象的__enter__()，即__enter__函数的结果
	with open('{}.html'.format(wd), 'wb') as file:
		file.write(bytes_)


# 封装一个函数，用于下载远程数据，如：下载图片
def download_img(url):
	# 通过切片获取图片名
	filename = url[url.rfind('/') + 1:]
	print(filename)
	# req = Request(url, headers={
	# 	'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.\
	# 	141 Safari/537.36'
	# })

	# # 发送get请求
	# res = urlopen(req)
	# assert res.code == 200
	# print('发送请求成功！')
	# # 读取并写入这个图片
	# # 注意：图片要以二进制写入
	# with open(filename, 'wb') as f:
	# 	f.write(res.read())

	# 直接将数据（网页、图片、视频）下载到本地
	urlretrieve(url, filename=filename)

	print('{}下载成功！'.format(filename))


if __name__ == '__main__':
	# 调用封装好的函数
	# search_baidu()
	download_img('https://img9.doubanio.com/view/photo/l_ratio_poster/public/p2626067725.jpg')
